/**
 * 
 */
package edu.umd.clip.lm.model.data;

import edu.umd.clip.lm.factors.FactorTuple;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class ContextReductionTrainingDataFilter implements TrainingDataFilter {
	private final int newContextSize;
	private final int numNullOvertFactors;
	private final int numNullHiddenFactors;
	
	/**
	 * @param overtOrder
	 * @param hiddenOrder
	 */
	public ContextReductionTrainingDataFilter(int overtOrder, int hiddenOrder) {
		this.newContextSize = Math.max(overtOrder-1, hiddenOrder-1);

		this.numNullOvertFactors = Math.min(newContextSize + 1 - overtOrder, newContextSize);
		this.numNullHiddenFactors = Math.min(newContextSize + 1 - hiddenOrder, newContextSize);

	}


	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.model.training.TrainingDataFilter#filterData(edu.umd.clip.lm.model.training.ContextFuturesPair)
	 */
	@Override
	public ContextFuturesPair filterData(ContextFuturesPair pair) {
		Context ctx = reduceContext(pair.getContext());
		
		return new ContextFuturesPair(ctx, pair.getFutures());
	}

	public Context reduceContext(Context oldContext) {
		final int oldContextSize = oldContext.data.length;
		Context ctx = new Context(newContextSize+1);
		
		if (newContextSize == oldContextSize) {
			ctx.data = oldContext.data.clone(); 
		} else {
			for(int i=oldContextSize-newContextSize; i<oldContextSize; ++i) {
				ctx.data[i - oldContextSize+newContextSize] = oldContext.data[i];
			}
		}
		for(int i=0; i<numNullOvertFactors; ++i) {
			ctx.data[i] &= FactorTuple.getHiddenMask();
		}
		for(int i=0; i<numNullHiddenFactors; ++i) {
			ctx.data[i] &= FactorTuple.getOvertMask();
		}
		return ctx;
	}

	public int getNewContextSize() {
		return newContextSize;
	}

	public int getNumNullOvertFactors() {
		return numNullOvertFactors;
	}

	public int getNumNullHiddenFactors() {
		return numNullHiddenFactors;
	}
}
